package service

import (
	"context"
	"encoding/json"
	"errors"
	"go.uber.org/zap"
	requestApi "hhos-mdijounery-server/api/request"
	"hhos-mdijounery-server/dao"
	"hhos-mdijounery-server/global"
	"hhos-mdijounery-server/library"
	"hhos-mdijounery-server/library/request"
	MidjourneyServer "hhos-mdijounery-server/proto"
)

type Midjourney struct {
	MidjourneyServer.UnimplementedMidjourneyServer
	midjourneyDao dao.MidjourneyDao
	midjourneyApi *library.MidJourneyApi
}

func NewMidjourney(midjourneyDao dao.MidjourneyDao, midjourneyApi *library.MidJourneyApi) *Midjourney {
	return &Midjourney{
		midjourneyDao: midjourneyDao,
		midjourneyApi: midjourneyApi,
	}
}

// Imagine 文生图
func (m *Midjourney) Imagine(ctx context.Context, in *MidjourneyServer.ImagineRequest) (*MidjourneyServer.ImagineResponse, error) {

	// 1. 添加数据库
	taskData, err := m.midjourneyDao.CreateTaskByImagine(in.Idempotent, in.Prompt, in.ImgUrl)
	if err != nil {
		return nil, err
	}

	// 2. 协程请求三方API
	api := &request.ImagineReq{
		Idempotent: in.Idempotent,
		Prompt:     in.Prompt,
		ImgUrl:     in.ImgUrl,
	}
	go m.midjourneyApi.ImagineApi(context.Background(), api)

	// 3.返回taskId
	return &MidjourneyServer.ImagineResponse{
		TaskId: int64(taskData.ID),
	}, nil
}

// Change 绘画改变
func (m *Midjourney) Change(ctx context.Context, params *MidjourneyServer.ChangeRequest) (*MidjourneyServer.ChangeResponse, error) {

	// 1. 查询数据库
	taskData, err := m.midjourneyDao.TaskItemById(params.ImageTaskId)
	if err != nil {
		return nil, err
	}

	// 1. 添加数据库
	insertTaskData, err := m.midjourneyDao.CreateTaskByChange(params.Idempotent, params.Action, params.Index)
	if err != nil {
		return nil, err
	}

	// 2. 协程请求三方API
	api := &request.ChangeReq{
		Idempotent: params.Idempotent,
		Action:     params.Action,
		Index:      params.Index,
		TaskId:     taskData.TaskID,
	}
	go m.midjourneyApi.ChangeApi(context.Background(), api)

	// 3.返回taskId
	return &MidjourneyServer.ChangeResponse{
		TaskId: int64(insertTaskData.ID),
	}, nil
}

// Callback 回调
func (m *Midjourney) Callback(ctx context.Context, params *requestApi.CallbackRequest) error {

	// 查询数据是否存在
	taskItem, err := m.midjourneyDao.TaskItem(params.Idempotent)
	// 判断进度顺序
	if taskItem.TaskProgress > params.TaskProgressInt {
		message := errors.New("回调顺序异常，不更新进度")
		global.Logger.Error("message:", zap.Error(message))
		return message
	}

	// 更新数据
	updateData := map[string]interface{}{
		"task_id":       params.TaskId,
		"task_status":   params.TaskStatus,
		"fail_reason":   params.FailReason,
		"task_progress": params.TaskProgressInt,
		"image_url":     params.ImageUrl,
		"generate_text": params.Prompt,
	}

	paramsJson, err := json.Marshal(params)
	if err != nil {
		global.Logger.Error("message-err:", zap.Error(err))
	}

	err = m.midjourneyDao.UpdateTaskItemByIdempotent(params.TaskId, params.Idempotent, params.ImageUrl, string(paramsJson), updateData)
	if err != nil {
		global.Logger.Error("message:", zap.Error(err))
	}

	return err
}
